
#ifndef MBED_TICKER_API_H
#define MBED_TICKER_API_H

#include <stdint.h>
#include <stdbool.h>

typedef uint32_t timestamp_t;

typedef uint64_t us_timestamp_t;

typedef struct ticker_event_s {
    us_timestamp_t         timestamp; 
    uint32_t               id;        
    struct ticker_event_s *next;     
} ticker_event_t;

typedef void (*ticker_event_handler)(uint32_t id);

typedef struct {
    uint32_t frequency;                           /*Hz*/
    uint32_t bits;                                /*8*/
} ticker_info_t;

typedef struct {
    void (*init)(void);                           
    uint32_t (*read)(void);                       
    void (*disable_interrupt)(void);             
    void (*clear_interrupt)(void);               
    void (*set_interrupt)(timestamp_t timestamp); 
    void (*fire_interrupt)(void);                
    void (*free)(void);                          
    const ticker_info_t *(*get_info)(void);      
    bool runs_in_deep_sleep;                     
} ticker_interface_t;

typedef struct {
    ticker_event_handler event_handler;
    ticker_event_t *head;              

    uint32_t period_num;               
    uint32_t period_den;                

    uint32_t bitmask;                   
    uint32_t max_delta;                 

    uint64_t max_delta_us;       

    uint32_t tick_last_read;           

    uint32_t tick_remainder;           

    us_timestamp_t present_time;       
    bool initialized;                  
    bool dispatching;                   
    bool suspended;                     

    int8_t period_num_shifts;           
    int8_t period_den_shifts;           

} ticker_event_queue_t;

typedef struct {
    const ticker_interface_t *interface; /**< Ticker's interface */
    ticker_event_queue_t *queue;         /**< Ticker's event queue */
} ticker_data_t;

#ifdef __cplusplus
extern "C" {
#endif

void ticker_set_handler(const ticker_data_t *const ticker, ticker_event_handler handler);

void ticker_irq_handler(const ticker_data_t *const ticker);

void ticker_remove_event(const ticker_data_t *const ticker, ticker_event_t *obj);

void ticker_insert_event(const ticker_data_t *const ticker, ticker_event_t *obj, timestamp_t timestamp, uint32_t id);

void ticker_insert_event_us(const ticker_data_t *const ticker, ticker_event_t *obj, us_timestamp_t timestamp, uint32_t id);

timestamp_t ticker_read(const ticker_data_t *const ticker);

us_timestamp_t ticker_read_us(const ticker_data_t *const ticker);

int ticker_get_next_timestamp(const ticker_data_t *const ticker, timestamp_t *timestamp);

int ticker_get_next_timestamp_us(const ticker_data_t *const ticker, us_timestamp_t *timestamp);

void ticker_suspend(const ticker_data_t *const ticker);

void ticker_resume(const ticker_data_t *const ticker);

int _ticker_match_interval_passed(timestamp_t prev_tick, timestamp_t cur_tick, timestamp_t match_tick);

#ifdef __cplusplus
}
#endif

#endif

/** @}*/
